package com.xyw.code.authentication.client.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xyw.code.authentication.client.provider.AuthProdiver;
import com.xyw.code.authentication.client.service.IAuthService;
import com.xyw.code.common.core.entity.vo.Result;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.stereotype.Service;

import java.util.stream.Stream;

/**
 * Created with IntelliJ IDEA.
 * User: xuyiwei
 * Date: 2020/4/22
 * Time: 下午2:46
 * Email: 1328312923@qq.com
 * Description: No Description
 **/
@Service
@Slf4j
public class AuthServiceImpl implements IAuthService {
    /**
     * Authorization认证开头是"bearer "
     */
    private static final String BEARER = "Bearer ";

    /**
     * jwt token 密钥，主要用于token解析，签名验证
     */
    @Value("${spring.security.oauth2.jwt.signingKey}")
    private String signingKey;

    /**
     * 不需要网关签权的url配置(/oauth,/open)
     * 默认/oauth开头是不需要的
     */
//    @Value("${gate.ignore.authentication.startWith}")
    private String ignoreUrls = "/oauth,/swagger-ui.html";

    @Autowired
    private AuthProdiver authProvider;

    @Override
    public boolean hasPermission(String authorization, String url, String method) {
        //判断token是不是这个bearer打头
        if(StringUtils.isBlank(authorization) || !authorization.startsWith(BEARER)){
            return false;
        }
        //判断token有没有过期
        if(invaildJwtToken(authorization)) {
            return false;
        }
        //最后去判断有没有权限
        Result<Boolean> result = authProvider.auth(authorization,url,method);
        log.debug("签权结果:{}", result.getData());
        if(result!=null && result.isSuccess() && (boolean)result.getData()){
            return true;
        }
        return false;
    }

    @Override
    public boolean invaildJwtToken(String authorization) {
        //true表示失效
        boolean invaild = Boolean.TRUE;
        try{
            Jws<Claims> claims = getJwtClaims(authorization);
            invaild = Boolean.FALSE;
        }catch (Exception e){
            log.info("token:{},已经失效。",authorization);
        }
        return invaild;
    }

    @Override
    public Jws<Claims> getJwtClaims(String jwtToken) {
        if (jwtToken.startsWith(BEARER)) {
            jwtToken = org.apache.commons.lang.StringUtils.substring(jwtToken, BEARER.length());
        }
        return Jwts.parser()  //得到DefaultJwtParser
                .setSigningKey(signingKey.getBytes()) //设置签名的秘钥
                .parseClaimsJws(jwtToken);
    }

    @Override
    public boolean ignoreUrl(String url) {
        return Stream.of(ignoreUrls.split(",")).anyMatch(ignoreUrl->url.startsWith(ignoreUrl));
    }

}
